package com.opennews.openplatform

import com.opennews.openplatform.constants.ServerCodeConstant
import com.opennews.openplatform.constants.ServerError
import groovy.transform.CompileStatic
import org.springframework.http.HttpStatus

@CompileStatic
class AuthenticationController extends BaseController {
    static allowedMethods = [
        register: "POST",
        unregister: "POST",
        login: "POST",
        refreshToken: "POST",
        switchAccountGroup: "POST"
    ]

    AccountGroupService accountGroupService
    AuthenticationService authenticationService
    UserService userService

    // region: Get actions.
    def index() {
        render("AuthenticationController")
    }

    def checkOnUsername() {
        def username = params.username.toString()
        def result = userService.checkOnUsername(username)

        sendDataResponse([usernameExists: result])
    }
    // endregion

    // region: Post actions.
    def register() {
        def requestBodyData = getRequestBodyData()
        def username = requestBodyData.username.toString()
        def password = requestBodyData.password.toString()
        def fullName = requestBodyData.fullName.toString()
        accountGroupService.register(username, password, fullName)

        sendStatusResponse(HttpStatus.NO_CONTENT)
    }

    def unregister() {
        def requestBodyData = getRequestBodyData()
        def password = requestBodyData.password.toString()

        def claims = getClaims()
        def userId = claims.id
        def username = claims.username

        if (userService.validatePassword(username, password)) {
            accountGroupService.unregister(userId)

            sendDataResponse([error: ""])
        } else {
            sendDataResponse([error: ServerError.ERROR_USER_ACCOUNT_BAD_CREDENTIAL])
        }
    }

    def login() {
        def requestBodyData = getRequestBodyData()

        def result = authenticationService.authenticateByCredential(requestBodyData.username.toString(),
            requestBodyData.password.toString(),
            getRequstIpAdress(),
            requestBodyData.deviceInfo as Map<String, String>,
            requestBodyData.systemInfo as Map<String, String>)

        if (SharedUtil.isNullOrEmpty(result.errorCode)) {
            sendDataResponse(result.myUserDetails)
        } else {
            sendErrorResponse(HttpStatus.UNAUTHORIZED.value(), ServerCodeConstant.UNAUTHORIZED, result.errorCode.toString(), request.getRequestURI().trim())
        }
    }

    def refreshToken() {
        def requestBodyData = getRequestBodyData()

        def result = authenticationService.refreshToken(requestBodyData.refreshToken.toString(),
            getRequstIpAdress(),
            requestBodyData.deviceInfo as Map<String, String>,
            requestBodyData.systemInfo as Map<String, String>)

        if (SharedUtil.isNullOrEmpty(result.errorCode)) {
            sendDataResponse(result.myUserDetails)
        } else {
            sendErrorResponse(HttpStatus.UNAUTHORIZED.value(), ServerCodeConstant.UNAUTHORIZED, result.errorCode.toString(), request.getRequestURI().trim())
        }
    }

    def switchAccountGroup() {
        def requestBodyData = getRequestBodyData()
        def accountGroupId = requestBodyData.accountGroupId.toString()
        def userId = getClaims().id
        def username = getClaims().username

        def result = authenticationService.switchAccountGroup(accountGroupId,
            userId,
            username,
            getRequstIpAdress(),
            requestBodyData.deviceInfo as Map<String, String>,
            requestBodyData.systemInfo as Map<String, String>)

        sendDataResponse(result)
    }
    // endregion
}